//
//  PLDirectorySearcher.m
//  Plankton
//
//  Created by Marc Schlichte on 16.06.09.
//  Copyright 2009 Framework Labs. All rights reserved.
//

#import "PLDirectorySearcher.h"


@interface PLDirectorySearcher ()

- (void)startSearch;
- (void)noteDiff;
- (void)noteFound:(NSSet *)found lost:(NSSet *)lost;

@end


@implementation PLDirectorySearcher 

@synthesize delegate, foundAids;

- (id)initWithPlatform:(PLPlatform *)platform
{
	if (self = [super init]) {
		directory = [[PLDirectory alloc] initWithPlatform:platform];
		directory.delegate = self;
		
		foundAids = [[NSMutableSet alloc] init];
		discoveredAids = [[NSMutableSet alloc] init];
	}
	return self;
}

- (void)dealloc
{
	[self stopSearchAids];
	[serviceToSearch release];
	[discoveredAids release];
	[foundAids release];
	[directory release];
	[super dealloc];
}

- (BOOL)startSearchAidsForService:(NSString *)service
{
	if ([serviceToSearch isEqual:service]) {
		return YES;
	}
	if (serviceToSearch) {
		return NO;
	}
	serviceToSearch = [service copy];
	[foundAids removeAllObjects];
	
	directory.autoDiscover = YES;
	directory.receiveUpdates = YES;
	
	[self startSearch];
	
	return YES;
}

- (BOOL)stopSearchAids
{
	if (serviceToSearch) {
		directory.autoDiscover = NO;
		directory.receiveUpdates = NO;
		[serviceToSearch release];
		serviceToSearch = nil;
		
		return YES;
	}
	else {
		return NO;
	}
}

- (void)startSearch
{
	if (!serviceToSearch) {
		return;
	}
	
	if ([directory isSearchingForAids]) {
		searchAgain = YES;
	}
	else {
		[discoveredAids removeAllObjects];
		[directory searchAidsForService:serviceToSearch];
	}
}

- (void)noteDiff
{
	NSMutableSet *found = [discoveredAids mutableCopy];
	[found minusSet:foundAids];
	NSMutableSet *lost = [foundAids mutableCopy];
	[lost minusSet:discoveredAids];
	
	[foundAids setSet:discoveredAids];
	
	[self noteFound:found lost:lost];
	
	[found release];
	[lost release];
}

- (void)noteFound:(NSSet *)found lost:(NSSet *)lost
{
	if ([delegate respondsToSelector:@selector(directorySearcher:found:lost:)]) {
		[delegate directorySearcher:self found:found lost:lost];
	}
	
	[[NSNotificationCenter defaultCenter] postNotificationName:PLDirectorySearcherDidChangeNotification 
														object:self
													  userInfo:[NSDictionary dictionaryWithObjectsAndKeys:found, @"found", lost, @"lost", nil]];
}

#pragma mark directory delegate methods

- (void)directory:(PLDirectory *)directory foundAid:(NSString *)aid forService:(NSString *)service
{
	[discoveredAids addObject:aid];
}

- (void)directory:(PLDirectory *)directory searchDoneForService:(NSString *)service
{
	[self noteDiff];
	
	if (searchAgain) {
		searchAgain = NO;
		[self startSearch];
	}
}

- (void)directoryChangedPeerSet:(PLDirectory *)directory
{
	[self startSearch];
}

- (void)directory:(PLDirectory *)directory addedAid:(NSString *)aid forService:(NSString *)service
{
	if ([service isEqual:serviceToSearch]) {
		[self noteFound:[NSSet setWithObject:aid] lost:[NSSet set]];
	}
}

- (void)directory:(PLDirectory *)directory removedAid:(NSString *)aid forService:(NSString *)service
{
	if ([service isEqual:serviceToSearch]) {
		[self noteFound:[NSSet set] lost:[NSSet setWithObject:aid]];
	}	
}

@end

NSString *const PLDirectorySearcherDidChangeNotification = @"PLDirectorySearcherDidChangeNotification";

